﻿using log4net;
using MSDAL;
using MSDAL.Implementation;
using MSWeb.Models;
using MSWEB.Implementation;
using PagedList;
using System;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Web.Mvc;
using MSWeb.Implementation;

namespace MSWeb.Controllers
{
    public class LekcjesController : Controller
    {
        private static int REPEAT_ADD_DAY = 7;
        ILog loger = LogManager.GetLogger(typeof(LekcjesController));
        private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private MSEntities db;
        private EventProcessor eventEngine;
        private DataRepository dataRepo;
        private LessonRepository lessonRepo;

        public LekcjesController()
        {
            db = new MSEntities();
            eventEngine = new EventProcessor();
            dataRepo = new DataRepository();
            lessonRepo = new LessonRepository();
        }

        [Authorize]
        public void UpdateLesson(int id, string newEventStart, string newEventEnd)
        {
            eventEngine.UpdateLesson(id, newEventStart, newEventEnd);
        }

        [Authorize]
        public JsonResult GetEvents(double start, double end)
        {
            try
            {
                var eventList = eventEngine.GetLessonList(start, end);
                var endDate = EventProcessor.ConvertFromUnixTimestamp(end);
                Session["data"] = endDate;
                ViewBag.IleLekcji = eventList.Count.ToString();
                var rows = eventList.ToArray();
                return Json(rows, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                loger.Error("Error! User: " + User.Identity.Name, ex);
                return Json(null, JsonRequestBehavior.AllowGet);
            }
        }

        [Authorize]
        public ActionResult ListaOdbytychLekcji(int? page)
        {
            int pageNumber = (page ?? 1);
            return View(db.Lekcje
                .OrderBy(i => i.Data)
                .Where(i => i.CzyUsunieta != true)
                .ToPagedList(pageNumber, ApplicationSettings.PageSize));
        }

        [Authorize]
        public ActionResult ZatwierdzLekcje()
        {
            try
            {
                DateTime data = DateTime.Parse(Session["data"].ToString());
                lessonRepo.ConfirmLessons(data);
            }
            catch (Exception ex)
            {
                loger.Error("Error! User: " + User.Identity.Name, ex);
                TempData["Error"] = "Zatwierdzanie lekcji - wystapil blad.";
                return RedirectToAction("WidokDzienny");
            }
            TempData["Error"] = "Zatwierdzanie lekcji - OK.";
            return RedirectToAction("WidokDzienny");
        }

        [Authorize]
        public ActionResult WidokDzienny()
        {
            Session["data"] = DateTime.Now.ToString();
            return View();
        }

        [Authorize]
        public ActionResult Index(int? page)
        {
            int pageNumber = (page ?? 1);
            var lekcje = db.Lekcje
               .Include(l => l.Nauczyciele)
               .Include(l => l.Sale)
               .Include(l => l.Uczniowie);
            ViewBag.IDNauczyciela = new SelectList(db.Nauczyciele, "IDNauczyciela", "Imie");
            ViewBag.IDSali = new SelectList(db.Sale, "IDSali", "NazwaSali");
            ViewBag.IDUcznia = new SelectList(db.Uczniowie, "IDUcznia", "Imie");
            return View(lekcje.OrderBy(i => i.IDLekcji)
                .ToPagedList(pageNumber, ApplicationSettings.PageSize));
        }

        [Authorize]
        public ActionResult Tworzenie()
        {
            ViewBag.IDInstrumentu = new SelectList(db.Instrumenty, "IDInstrumentu", "NazwaInstrumentu");
            ViewBag.IDNauczyciela = dataRepo.GetNauczyciele();
            ViewBag.IDSali = new SelectList(db.Sale, "IDSali", "NazwaSali");
            ViewBag.IDUcznia = dataRepo.GetUczniowie();
            return PartialView("_TworzenieLekcji");
        }

        [Authorize]
        public ActionResult Edycja(int? id)
        {
            if (!id.HasValue)
            {
                TempData["Error"] = "Nieodnaleziono podanego rekordu";
                return RedirectToAction("Index");
            }
            if (db.Lekcje.Any(i => i.IDLekcji == id))
            {
                Lekcje editedLesson = db.Lekcje.First(i => i.IDLekcji == id);
                ViewBag.IDUcznia = dataRepo.GetNameAndSurnameForStudent(editedLesson.IDUcznia);
                ViewBag.IDNauczyciela = dataRepo.GetNameAndSurnameForTeacher(editedLesson.IDNauczyciela);

                ViewBag.IDInstrumentu = new SelectList(db.Instrumenty, "IDInstrumentu", "NazwaInstrumentu");
                ViewBag.IDSali = new SelectList(db.Sale, "IDSali", "NazwaSali");

                return PartialView("_EdycjaLekcji", editedLesson);
            }
            TempData["Error"] = "Nieodnaleziono podanego rekordu";
            return RedirectToAction("Index");
        }

        [Authorize]
        public ActionResult EdycjaLekcji()
        {
            return View();
        }

        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult EdycjaLekcji(EdycjaLekcjiInitVM initVm)
        {
            return RedirectToAction("IndexZData", initVm.DataLekcji);
        }

        [Authorize]
        public ActionResult IndexZData(DateTime? Date)
        {
            if (Date.HasValue)
            {
                DateTime dataOnly = Date.Value.Date;
                var res = db.Lekcje
                    .Include(l => l.Nauczyciele)
                    .Include(l => l.Sale)
                    .Include(l => l.Uczniowie)
                    .Where(i => i.Data.Value.Year == dataOnly.Date.Year
                    && i.Data.Value.Month == dataOnly.Date.Month
                    && i.Data.Value.Day == dataOnly.Date.Day)
                    .ToList();
                if (res.Count > 0)
                {
                    return View(res);
                }
                else
                {
                    TempData["Error"] = "Brak lekcji w tej selekcji";
                    return RedirectToAction("EdycjaLekcji");
                }
            }
            else
            {
                TempData["Error"] = "Brak lekcji w tej selekcji";
                return RedirectToAction("EdycjaLekcji");
            }
        }

        [Authorize]
        public ActionResult Detale(int id)
        {
            Lekcje lekcje = db.Lekcje.Find(id);
            if (lekcje == null)
            {
                return HttpNotFound();
            }
            var vm = db.Lekcje.First(i => i.IDLekcji == id);
            return PartialView("_LekcjeDetalePartial", vm);
        }

        // GET: Lekcjes/Details/5
        [Authorize]
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Lekcje lekcje = db.Lekcje.Find(id);
            if (lekcje == null)
            {
                return HttpNotFound();
            }
            return View(lekcje);
        }

        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult Create(NewLessonViewModel lekcje)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    if (!lekcje.Data.HasValue)
                    {
                        TempData["Error"] = "Podaj datę rozpoczęcia lekcji.";
                        return RedirectToAction("WidokDzienny");
                    }
                    if (!lekcje.CenaLekcjiUcznia.HasValue)
                    {
                        TempData["Error"] = "Podaj koszt lekcji.";
                        return RedirectToAction("WidokDzienny");
                    }
                    if (!lekcje.CzasTrwaniaLekcji.HasValue)
                    {
                        TempData["Error"] = "Podaj czas trwania lekcji.";
                        return RedirectToAction("WidokDzienny");
                    }
                    if (lekcje.IleCykli.HasValue && lekcje.IleCykli > 5)
                    {
                        TempData["Error"] = "Podano zbyt odległą datę.";
                        return RedirectToAction("WidokDzienny");
                    }
                    //TO DO data aktualna - data wybrana < data z 5 tygodni
                    lekcje.CenaLekcjiNauczyciela = db.Nauczyciele
                            .FirstOrDefault(i => i.IDNauczyciela == lekcje.IDNauczyciela)
                            .WynagrodzenieZaLekcje;
                    lekcje.CzyUczenL4 = false;
                    if (!lessonRepo.SaveNewLesson(lekcje))
                    {
                        TempData["Error"] = "Błąd podczas dodawania lekcji.";
                        return RedirectToAction("WidokDzienny");
                    }
                    if (lekcje.IleCykli.HasValue)
                    {
                        DateTime StartDate = lekcje.Data.Value;
                        for (int i = 1; i <= lekcje.IleCykli; i++)
                        {
                            lekcje.Data = StartDate.AddDays(i * REPEAT_ADD_DAY);
                            if (!lessonRepo.SaveNewLesson(lekcje))
                            {
                                TempData["Error"] = "Wystapił błąd podczas dodawania wpisu.";
                                return RedirectToAction("WidokDzienny");
                            }
                        }
                        TempData["Error"] = "Lekcja dodana poprawnie.";
                        return RedirectToAction("WidokDzienny");
                    }
                }
                else
                {
                    TempData["Error"] = "Wystapił błąd podczas dodawania wpisu.";
                    return RedirectToAction("WidokDzienny");
                }
                TempData["Error"] = "Lekcja dodana poprawnie.";
                return RedirectToAction("WidokDzienny");
            }
            catch (Exception ex)
            {
                TempData["Error"] = "Wystapił błąd podczas dodawania wpisu.";
                log.Error(ex.Message);
                log.Error(ex.InnerException);
                return RedirectToAction("WidokDzienny");
            }
        }


        // GET: Lekcjes/Edit/5
        [Authorize]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Lekcje lekcje = db.Lekcje.Find(id);
            if (lekcje == null)
            {
                return HttpNotFound();
            }
            ViewBag.IDNauczyciela = new SelectList(db.Nauczyciele, "IDNauczyciela", "Imie", lekcje.IDNauczyciela);
            ViewBag.IDSali = new SelectList(db.Sale, "IDSali", "NazwaSali", lekcje.IDSali);
            ViewBag.IDUcznia = new SelectList(db.Uczniowie, "IDUcznia", "Imie", lekcje.IDUcznia);
            return View(lekcje);
        }

        // POST: Lekcjes/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [Authorize]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(Lekcje lekcje)
        {
            try
            {
                db.Lekcje.Attach(lekcje);
                db.Entry(lekcje).Property(i => i.Data).IsModified = true;
                db.Entry(lekcje).Property(i => i.IDSali).IsModified = true;
                db.Entry(lekcje).Property(i => i.KosztLekcji).IsModified = true;
                db.Entry(lekcje).Property(i => i.CzasTrwaniaLekcji).IsModified = true;
                if (lekcje.CzyZatwierdzona != null)
                    db.Entry(lekcje).Property(i => i.CzyZatwierdzona).IsModified = true;
                if (lekcje.CzyUsunieta != null)
                    db.Entry(lekcje).Property(i => i.CzyUsunieta).IsModified = true;
                db.SaveChanges();
                TempData["Error"] = "Edycja lekji - OK.";
            }
            catch (Exception ex)
            {
                TempData["Error"] = "Błąd podczas edytowania lekcji.";
            }
            return RedirectToAction("WidokDzienny");
        }

        // GET: Lekcjes/Delete/5
        [Authorize]
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Lekcje lekcje = db.Lekcje.Find(id);
            if (lekcje == null)
            {
                return HttpNotFound();
            }
            return View(lekcje);
        }

        // POST: Lekcjes/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        [Authorize]
        public ActionResult DeleteConfirmed(int id)
        {
            lessonRepo.DeleteLesson(id);
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
